<?php

namespace Helper;

/**
 * 字符串帮助类
 * Class StringHelper
 * @package Helper
 */
class StringHelper extends BaseHelper
{

    /** 获取随机数字
     * @param int $length
     * @param int $type
     * @return string
     */
    public static function getRandom($length = 4, $type = 1)
    {
        switch ($type) {
            case 1:
                $string = '1234567890';
                break;

            case 2:
                $string = 'abcdefghijklmnopqrstuvwxyz';
                break;

            case 3:
                $string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
                break;

            case 4:
                $string = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
                break;

            case 5:
                $string = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
                break;
        }
        $output = '';
        for ($i = 0; $i < $length; $i++) {
            $pos = mt_rand(0, strlen($string) - 1);
            $output .= $string[$pos];
        }
        return $output;
    }
    /**
     * 传入参数过滤
     * @param $arr
     * @return
     */
    public static function filterInput($arr)
    {
        if (is_array($arr)) {
            foreach ($arr as $k => $v) {
                if ($v) {
                    $arr[$k] = self::filter(self::stripSQLChars(self::stripHTML(trim($v), true)));
                }
            }
        } else {
            $arr = self::filter(self::stripSQLChars(self::stripHTML(trim($arr), true)));
        }
        return $arr;
    }

    /**
     * 参数过滤
     * @param $arr
     */
    public static function filter($str)
    {
        return $str;
//        if (!get_magic_quotes_gpc()) {
////            return addslashes($str);
////        } else {
////            return $str;
////        }
    }

    /**
     *  Strip specail SQL chars
     * @param $str
     * @return mixed
     */
    public static function stripSQLChars($str)
    {
        $replace = array('SELECT', 'INSERT', 'DELETE', 'UPDATE', 'CREATE', 'DROP', 'VERSION', 'DATABASES',
            'TRUNCATE', 'HEX', 'UNHEX', 'CAST', 'DECLARE', 'EXEC', 'SHOW', 'CONCAT', 'TABLES', 'CHAR', 'FILE',
            'SCHEMA', 'DESCRIBE', 'UNION', 'JOIN', 'ALTER', 'RENAME', 'LOAD', 'FROM', 'SOURCE', 'INTO', 'LIKE', 'PING', 'PASSWD');

        return str_ireplace($replace, '', $str);
    }

    /**
     * 对HTML、违法关键字进行排除
     * @param $str
     * @param bool $xss
     * @return mixed
     */
    public static function stripHTML($str, $xss = true)
    {
        $replace = array('SELECT', 'INSERT', 'DELETE', 'UPDATE', 'CREATE', 'DROP', 'VERSION', 'DATABASES',
            'TRUNCATE', 'HEX', 'UNHEX', 'CAST', 'DECLARE', 'EXEC', 'SHOW', 'CONCAT', 'TABLES', 'CHAR', 'FILE',
            'SCHEMA', 'DESCRIBE', 'UNION', 'JOIN', 'ALTER', 'RENAME', 'LOAD', 'FROM', 'SOURCE', 'INTO', 'LIKE', 'PING', 'PASSWD');

        return str_ireplace($replace, '', $str);
    }

    //根据身份证获取年龄和性别
    public static function getAgeAndSexByIDcard($idcard)
    {
        $result = array('age' => -1, 'sex' => -1);
        if (strlen($idcard) == 15 OR strlen($idcard) == 18) {
            $result['sex'] = substr($idcard, (strlen($idcard) == 18 ? -2 : -1), 1) % 2 ? '1' : '2';
            //过了这年的生日才算多了1周岁
            $date = strtotime(substr($idcard, 6, 8));
            //获得出生年月日的时间戳
            $today = strtotime('today');
            //获得今日的时间戳
            $diff = floor(($today - $date) / 86400 / 365);
            //得到两个日期相差的大体年数
            //strtotime加上这个年数后得到那日的时间戳后与今日的时间戳相比
            $result['age'] = strtotime(substr($idcard, 6, 8) . ' +' . $diff . 'years') > $today ? ($diff + 1) : $diff;
        }
        return $result;
    }

    //检查是否为email格式
    public static function isEmail($email)
    {
        if (!$email) {
            return false;
        }
        return preg_match('/^[_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,4}$/i', $email);
    }

    //检查是否为手机格式
    public static function isPhoneNumber($phone)
    {
        if (!$phone) {
            return false;
        }
        return preg_match('/^((\(d{2,3}\))|(\d{3}\-))?1(3|4|5|6|7|8|9)\d{9}$/', $phone);
    }

    /*
     * 处理年份格式
     * 符合年份格式则原数据返回，不符合则输出当前年份
     */
    public static function handleYear($year)
    {
        $year = (int)$year;
        if ($year >= 1970 && $year <= 2100 ){
            return $year;
        }else{
            return date('Y');
        }
    }

    /*
     * 处理月份格式
     * 符合月份格式则原数据返回，不符合则输出当前年份
     */
    public static function handleMonth($month)
    {
        $month = (int)$month;
        if ($month >= 1 && $month <= 12 ){
            return $month;
        }else{
            return date('m');
        }
    }
    
    /**
     * 根据年月获取指定月份起止时间戳
     * (此处不做年月格式检查)
     */
    public static function YearMonthToTimeStamp($year, $month)
    {
        $month = $year . "-" . $month;

        return [
            'startTime' => strtotime($month),
            'endTime'   => mktime(23, 59, 59, date('m', strtotime($month))+1, 00),
        ];
    }

    /**
     *给定一个日期，获取其本月的第一天日期
     */
    public static function getCurMonthFirstDay($date) {
        return date('Y-m-01', strtotime($date));
    }

    /**
     *给定一个日期，获取其本月的最后一天日期
     */
    public static function getCurMonthLastDay($date) {
        return date('Y-m-d', strtotime(date('Y-m-01', strtotime($date)) . ' 1 month -1 day'));
    }


    /***********************************************************
     * 截取中文字符串
     **********************************************************/
    public static function subString_UTF8($str, $start, $lenth)
    {
        $len = strlen($str);
        $r = array();
        $n = 0;
        $m = 0;
        for ($i = 0; $i < $len; $i++) {
            $x = substr($str, $i, 1);
            $a = base_convert(ord($x), 10, 2);
            $a = substr('00000000' . $a, -8);
            if ($n < $start) {
                if (substr($a, 0, 1) == 0) {
                } elseif (substr($a, 0, 3) == 110) {
                    $i += 1;
                } elseif (substr($a, 0, 4) == 1110) {
                    $i += 2;
                }
                $n++;
            } else {
                if (substr($a, 0, 1) == 0) {
                    $r[] = substr($str, $i, 1);
                } elseif (substr($a, 0, 3) == 110) {
                    $r[] = substr($str, $i, 2);
                    $i += 1;
                } elseif (substr($a, 0, 4) == 1110) {
                    $r[] = substr($str, $i, 3);
                    $i += 2;
                } else {
                    $r[] = '';
                }
                if (++$m >= $lenth) {
                    break;
                }
            }
        }
        return implode('', $r);
    }


    //隐藏手机号
    public static function convertMobile($mobile)
    {
        $pattern = "/(1\d{1,2})\d\d(\d{0,3})/";
        $replacement = "\$1*****\$3";

        $mobile = preg_replace($pattern, $replacement, $mobile);
        return $mobile;
    }

    //隐藏邮箱
    public static function convertEmail($email)
    {
        $email_array = explode('@', $email);
        $length = strlen($email_array[0]);
        switch ($length) {
            case 1:
                $start = $email_array[0];
                break;
            case 2:
                $start = self::subString_UTF8($email_array[0], 0, 1) . '*';
                break;
            case 3:
                $start = self::subString_UTF8($email_array[0], 0, 2) . '*';
                break;
            default:
                $start = self::subString_UTF8($email_array[0], 0, 3);
                for ($i = 0; $i < $length; $i++) {
                    $start .= '*';
                }
        }

        $email = $start . '@' . $email_array[1];
        return $email;
    }

    //隐藏身份证
    public static function convertIdCard($IdCard)
    {
        $pattern = "/(\d{0,4})\d\d\d\d\d\d\d\d(\d{0,3})/";
        $replacement = "\$1**********\$3";

        $IdCard = preg_replace($pattern, $replacement, $IdCard);
        return $IdCard;
    }

    //隐藏银行卡号
    public static function convertBankCard($BankCard)
    {
        $start = self::subString_UTF8($BankCard, 0, 4);
        $end = self::subString_UTF8($BankCard, strlen($BankCard) - 4, 4);
        return $start . '******' . $end;
    }

    //隐藏营业执照号
    public static function convertBusCard($buscard)
    {
        $start = substr($buscard, 0, 4);
        $end = substr($buscard, strlen($buscard) - 3, 3);
        return $start . '******' . $end;
    }

    //隐藏姓名
    public static function convertName($str)
    {
        if (!preg_match("[^\x80-\xff]", $str)) {
            $i = mb_strlen($str, 'utf-8');
            $first = mb_substr($str, 0, 1, 'utf-8');
            $middle = '';
            if ($i > 2) {
                $last = mb_substr($str, $i - 1, 1, 'utf-8');
                for ($k = 1; $k < $i - 1; $k++) {
                    $middle .= "**";
                }
            } elseif ($i = 2) {
                $last = "**";
            } else {
                $last = mb_substr($str, 1, 1, 'utf-8');
            }
            return $first . $middle . $last;
        } else {
            $i = strlen($str);
            $first = substr($str, 0, 1);
            $middle = '';
            if ($i > 2) {
                $last = substr($str, $i - 1, 1);
                for ($k = 1; $k < $i - 1; $k++) {
                    $middle .= "*";
                }
            } elseif ($i = 2) {
                $last = "**";
            } else {
                $last = substr($str, 1, 1);
            }
            return $first . $middle . $last;
        }
    }

    /**
     * 隐藏字段，在中间添加星星（适用于公司名称、公司地址、银行卡，电话）
     * @param $str 要转换的含有字符串
     * @param $count =4 前后各显示的字符长度，如果长度不够，会自动-1
     */
    public static function convertZhStr($str, $count = 4)
    {
        $str = trim($str);
        $len = mb_strlen($str, 'utf-8');
        $differ = $len - $count * 2;
        if ($differ >= 0) {
            $left_str = self::subString_UTF8($str, 0, $count);
            $right_str = self::subString_UTF8($str, $len - $count, $count);
            $middle_str = '';
            $middle_str = '****';
            $ret = $left_str . $middle_str . $right_str;
        } else {
            // 长度不够，递归到$count=1;
            if ($count <= 1) {
                $ret = $str;
            } else {
                $count2 = $count - 1;
                return self::convertZhStr($str, $count2);
            }
        }
        return $ret;
    }

    /**
     * 求今天与传入日期相差的天数
     * (针对1970年1月1日之后，求之前可以采用泰勒公式)
     * @param string $day
     * @return number
     */
    public static function diffBetweenDays($day1, $day2)
    {
        if (!is_numeric($day1)) {
            $second1 = strtotime($day1);
        } else {
            $second1 = $day1;
        }
        if (!is_numeric($day2)) {
            $second2 = strtotime($day2);
        } else {
            $second2 = $day2;
        }
        return floor(($second1 - $second2) / 86400);
    }


    /**
     * 超出指定长度字符串后面用省略号表示
     * @param $string 目标字符串
     * @param $length 指定长度
     * @return string
     */
    public static function ellipsisStrings($string, $length){
        return mb_strlen($string) > $length ? self::subString_UTF8($string, 0, $length) . '...' : $string;
    }

    /**
     * 如果传入时间属于今年日期，返回“月-日”， 否则返回“年-月-日”
     * @param $timestamp 时间戳
     */
    public static function shortDate($timestamp){
        if(strtotime(date('Y-m-d H:i:s',$timestamp)) !== $timestamp) {
            return false; //传入的不是时间戳
        }

        if ($timestamp >= strtotime(date('Y-01-01 00:00:00')) AND $timestamp <= strtotime(date('Y-12-31 23:59:59'))){
            return date('m-d', $timestamp);
        }else{
            return date('Y-m-d', $timestamp);
        }

    }

    public static function password($password, $secret = '')
    {
        $pwd = array();
        $salt = substr(uniqid(rand()), -6);
        $pwd['secret'] = $secret ? $secret : $salt;
        $pwd['password'] = md5(md5(trim($password)) . $pwd['secret'] . 'onepeople');
        return $secret ? $pwd['password'] : $pwd;
    }

    /**
     * 银行排序函数
     * @param $param
     * @return array
     */
    public static function sortBankSupport($param)
    {
        $i = 0;
        $resBankArray = [];//四大行
        $otherBankArray = [];
        $bankNameArray = ['工商银行', '农业银行', '中国银行', '建设银行'];
        foreach ($param as $v => $k) {
            if (in_array($k['bankName'], $bankNameArray)) {
                $resBankArray[$i]['id'] = $k['id'];
                $resBankArray[$i]['bankName'] = $k['bankName'];
            } else {
                $otherBankArray[$i]['id'] = $k['id'];
                $otherBankArray[$i]['bankName'] = $k['bankName'];
            }
            $i++;
        }
        //合并数组
        $resBankArray = array_merge($resBankArray, $otherBankArray);
        return $resBankArray;
    }

    /********************php验证身份证号码是否正确函数*********************/
    public static function is_idcard( $code )
    {
        $code = strtoupper($code);
        $regx = "/(^\d{15}$)|(^\d{17}([0-9]|X)$)/";
        $arr_split = array();
        if(!preg_match($regx, $code))
        {
            return FALSE;
        }
        if(15==strlen($code)) //检查15位 
        {
            $regx = "/^(\d{6})+(\d{2})+(\d{2})+(\d{2})+(\d{3})$/";

            @preg_match($regx, $code, $arr_split);
            //检查生日日期是否正确 
            $dtm_birth = "19".$arr_split[2] . '/' . $arr_split[3]. '/' .$arr_split[4];
            if(!strtotime($dtm_birth))
            {
                return FALSE;
            } else {
                return TRUE;
            }
        }
        else      //检查18位 
        {
            $regx = "/^(\d{6})+(\d{4})+(\d{2})+(\d{2})+(\d{3})([0-9]|X)$/";
            @preg_match($regx, $code, $arr_split);
            $dtm_birth = $arr_split[2] . '/' . $arr_split[3]. '/' .$arr_split[4];
            if(!strtotime($dtm_birth)) //检查生日日期是否正确 
            {
                return FALSE;
            }
            else
            {
                //检验18位身份证的校验码是否正确。 
                //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。 
                $arr_int = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
                $arr_ch = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
                $sign = 0;
                for ( $i = 0; $i < 17; $i++ )
                {
                    $b = (int) $code{$i};
                    $w = $arr_int[$i];
                    $sign += $b * $w;
                }
                $n = $sign % 11;
                $val_num = $arr_ch[$n];
                if ($val_num != substr($code,17, 1))
                {
                    return FALSE;
                } //phpfensi.com 
                else
                {
                    return TRUE;
                }
            }
        }

    }

    /**
     * 创建订单号
     * @param string $start
     * @param string $end
     * @return string
     */
    public static function createSn( $start = '',  $end = '000000')
    {
        $sn = mt_rand(100000, 999999);
        //str_pad填充字符串,STR_PAD_LEFT填充字符串的左侧
        $end = str_pad($end, 6, '0', STR_PAD_LEFT);
        return $start . date('YmdHis') . $end . $sn;
    }
}